package com.ihr360.payroll.service.payperiod.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ihr360.commons.context.session.Ihr360SessionContextHolder;
import com.ihr360.commons.exception.Ihr360Exception;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.lang.StringUtils;
import com.ihr360.commons.model.meta.table.DynamicCell;
import com.ihr360.commons.specification.Ihr360Specification;
import com.ihr360.commons.vo.PageData;
import com.ihr360.entity.BasicStaffInfoEntity;
import com.ihr360.excel.ExcelUtil;
import com.ihr360.excel.entity.ExportParams;
import com.ihr360.payroll.dao.StaffPayPeriodTermSalaryRepository;
import com.ihr360.payroll.dao.StaffPayrollInfoRepository;
import com.ihr360.payroll.model.dto.salary.report.HistoryPayPeriod;
import com.ihr360.payroll.model.dto.salary.report.MergeSalaryReportTermSalary;
import com.ihr360.payroll.model.dto.salary.task.period.PayPeriodTerm;
import com.ihr360.payroll.model.dto.salary.task.period.StaffPayPeriodTermSalary;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.StaffSalarySnapshot;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.StaffSalaryTermId;
import com.ihr360.payroll.model.dto.staff.StaffPayrollInfo;
import com.ihr360.payroll.model.dto.staff.embeddable.StaffBankCard;
import com.ihr360.payroll.model.response.salaryreport.BankPlateResponse;
import com.ihr360.payroll.model.response.salaryreport.SalaryHeader;
import com.ihr360.payroll.model.response.salaryreport.SalaryReportResponse;
import com.ihr360.payroll.model.response.salaryreport.StaffSalaryData;
import com.ihr360.payroll.model.response.salaryreport.StaffSalaryResponse;
import com.ihr360.payroll.model.vo.SalaryFieldEntity;
import com.ihr360.payroll.request.salaryReport.SalaryReportRequest;
import com.ihr360.payroll.service.payperiod.StaffPayPeriodTermSalaryService;
import com.ihr360.payroll.service.salaryreport.HistoryPayPeriodService;
import com.ihr360.payroll.service.salaryreport.HistorySalaryPlanService;
import com.ihr360.payroll.service.salaryreport.MergeReportStaffSalaryService;
import com.ihr360.payroll.service.salaryreport.MergeSalaryReportTermSalaryService;
import com.ihr360.rest.reposity.SimpleRestReposity;
import com.ihr360.rest.service.AbstractSimpleRestServiceImpl;
import com.ihr360.shared.basicstaffinfo.dto.SyncedBasicStaffInfo;
import com.ihr360.shared.basicstaffinfo.service.BasicStaffInfoService;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class StaffPayPeriodTermSalaryServiceImpl extends AbstractSimpleRestServiceImpl<StaffPayPeriodTermSalary, StaffSalaryTermId> implements StaffPayPeriodTermSalaryService {

    private Logger logger = LoggerFactory.getLogger(StaffPayPeriodTermSalaryServiceImpl.class);


    //实发合计code
    private static final String TOTAL_TAKE_HOME_PAY = "totaltakehomepay";

    @Autowired
    private StaffPayPeriodTermSalaryRepository staffPayPeriodTermSalaryRepository;

    @Autowired
    private BasicStaffInfoService basicStaffInfoService;

    @Autowired
    private HistorySalaryPlanService historySalaryPlanService;

    @Autowired
    private StaffPayrollInfoRepository staffPayrollInfoRepository;

    @Autowired
    private MergeSalaryReportTermSalaryService mergeSalaryReportTermSalaryService;

    @Autowired
    private MergeReportStaffSalaryService mergeReportStaffSalaryService;

    @Autowired
    private HistoryPayPeriodService historyPayPeriodService;

    @Override
    public SimpleRestReposity<StaffPayPeriodTermSalary, StaffSalaryTermId> getSimpleRestReposity() {
        return staffPayPeriodTermSalaryRepository;
    }

    @Override
    public List<StaffPayPeriodTermSalary> loadPayPeriodSalaryOfStaffs(Long termId, Set<String> staffIds) {
        return staffPayPeriodTermSalaryRepository.findByIdTermIdAndIdStaffIdIn(termId, staffIds);
    }

    @Override
    public List<StaffPayPeriodTermSalary> getStaffSalaryByTerms(List<Long> termIds) {
        return staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdTermIdIn(Ihr360SessionContextHolder.getCompanyId(), termIds);
    }

    @Override
    public Map<String, StaffPayPeriodTermSalary> loadPayperiodSalaryOfStaffsWithMapResult(Long termId, Set<String> staffIds) {
        List<StaffPayPeriodTermSalary> salaries = staffPayPeriodTermSalaryRepository.findByIdTermIdAndIdStaffIdIn(termId, staffIds);
        if (CollectionUtils.isEmpty(salaries)) {
            return Maps.newConcurrentMap();
        }
        Map<String, StaffPayPeriodTermSalary> salaryMap = salaries.stream().collect(Collectors.toMap(StaffPayPeriodTermSalary::getStaffId, s -> s));
        return salaryMap;
    }

    private List<StaffSalaryResponse> getStaffSalaryResponse(String companyId, List<StaffPayPeriodTermSalary> salaryList) {
        List<StaffSalaryResponse> list = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(salaryList)) {
            List<String> staffIds = salaryList.stream().map(StaffPayPeriodTermSalary::getStaffId).collect(Collectors.toList());
            List<BasicStaffInfoEntity> staffInfoList = basicStaffInfoService.getStaffList(companyId, staffIds);
            Map<String, BasicStaffInfoEntity> staffMap = staffInfoList.stream().collect(Collectors.toMap(BasicStaffInfoEntity::getId, Function.identity()));
            for (StaffPayPeriodTermSalary salary : salaryList) {
                if (salary == null) {
                    continue;
                }
                if (!staffMap.containsKey(salary.getStaffId())) {
                    continue;
                }
                //汇总数据
                StaffSalaryResponse salaryResponse = new StaffSalaryResponse();
                if (salary.getSummarizedData() != null) {
                    StaffSalaryData staffSalaryData = new StaffSalaryData();
                    BeanUtils.copyProperties(salary.getSummarizedData(), staffSalaryData);
                    salaryResponse.setSummaryData(staffSalaryData);
                }
                //分段数据
                if (salary.getPhasedData() != null && CollectionUtils.isNotEmpty(salary.getPhasedData().getPhasedData())
                        && salary.getPhasedData().getPhasedData().size() > 1) {
                    List<StaffSalaryData> parseData = Lists.newArrayList();
                    for (StaffSalarySnapshot salarySnapshot : salary.getPhasedData().getPhasedData()) {
                        StaffSalaryData staffSalaryData = new StaffSalaryData();
                        BeanUtils.copyProperties(salarySnapshot, staffSalaryData);
                        parseData.add(staffSalaryData);
                    }
                    salaryResponse.setPhasedData(parseData);
                }
                BasicStaffInfoEntity staffInfoEntity = staffMap.get(salary.getStaffId());
                BeanUtils.copyProperties(staffInfoEntity, salaryResponse);
                list.add(salaryResponse);
            }
        }
        return list;
    }

    @Override
    public SalaryReportResponse queryStaffSalaryPageData(String companyId, SalaryReportRequest reportRequest) {
        SalaryReportResponse reportResponse = new SalaryReportResponse();
        List<BasicStaffInfoEntity> staffList = queryStaffList(companyId, reportRequest);
        if (CollectionUtils.isEmpty(staffList)) {
            return reportResponse;
        }
        List<String> staffIdList = staffList.stream().map(BasicStaffInfoEntity::getId).collect(Collectors.toList());
        Page<StaffPayPeriodTermSalary> page = staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdTermIdAndIdStaffIdIn(companyId, reportRequest.getTermId(), staffIdList, reportRequest.getPageable());
        List<StaffSalaryResponse> list = getStaffSalaryResponse(companyId, page.getContent());
        reportResponse.setStaffSalary(new PageData<>(page.getTotalPages(), page.getTotalElements(), list));
        return reportResponse;
    }


    private List<BankPlateResponse> getBankPlateList(String companyId, SalaryReportRequest reportRequest, List<StaffPayPeriodTermSalary> salaryList, List<BasicStaffInfoEntity> staffInfoList) {
        List<BankPlateResponse> list = Lists.newArrayList();

        if (CollectionUtils.isEmpty(salaryList) || CollectionUtils.isEmpty(staffInfoList)) {
            return list;
        }
        List<String> staffIdList = staffInfoList.stream().map(BasicStaffInfoEntity::getId).collect(Collectors.toList());
        List<StaffPayrollInfo> staffPayrollInfoList = staffPayrollInfoRepository.findByCompanyIdAndStaffIdIn(companyId, staffIdList);
        Map<String, StaffPayrollInfo> staffPayrollInfoMap = staffPayrollInfoList.stream().collect(Collectors.toMap(staffPayrollInfo -> staffPayrollInfo.getStaff().getId(), Function.identity()));
        Map<String, BasicStaffInfoEntity> staffMap = staffInfoList.stream().collect(Collectors.toMap(BasicStaffInfoEntity::getId, Function.identity()));
        for (StaffPayPeriodTermSalary salary : salaryList) {
            if (salary == null || !staffMap.containsKey(salary.getStaffId())) {
                continue;
            }
            BasicStaffInfoEntity staffInfoEntity = staffMap.get(salary.getStaffId());
            BankPlateResponse bankPlateResponse = new BankPlateResponse();
            bankPlateResponse.setStaffName(staffInfoEntity.getStaffName());
            bankPlateResponse.setIdCardNo(staffInfoEntity.getIdCardNo());
            bankPlateResponse.setRemark("");
            //银行信息填充
            if (staffPayrollInfoMap.containsKey(salary.getStaffId())) {
                StaffPayrollInfo staffPayrollInfo = staffPayrollInfoMap.get(salary.getStaffId());
                if (staffPayrollInfo != null && staffPayrollInfo.getStaffBankCard() != null) {
                    StaffBankCard staffBankCard = staffPayrollInfo.getStaffBankCard();
                    bankPlateResponse.setBankCardHolderName(staffBankCard.getBankCardHolderName1());
                    bankPlateResponse.setBankCardName(staffBankCard.getBankName1());
                    bankPlateResponse.setBankCardNo(staffBankCard.getBankCardNo1());
                }
            }
            String salaryFieldCode = reportRequest.getSalaryFieldCode();
            if (StringUtils.isNotBlank(salaryFieldCode)) {//根据传入的列，默认为 实发合计
                if (checkSummaryDate(salary.getSummarizedData(), salaryFieldCode)) {
                    bankPlateResponse.setMoney(salary.getSummarizedData().getData().get(salaryFieldCode).getCellValue());
                }
            } else {//默认获取 实发合计
                if (checkSummaryDate(salary.getSummarizedData(), TOTAL_TAKE_HOME_PAY)) {
                    bankPlateResponse.setMoney(salary.getSummarizedData().getData().get(TOTAL_TAKE_HOME_PAY).getCellValue());
                }
            }
            list.add(bankPlateResponse);
        }

        return list;
    }

    private List<BankPlateResponse> getMergeReportBankPlateList(String companyId, SalaryReportRequest reportRequest, List<StaffSalaryResponse> salaryList, List<BasicStaffInfoEntity> staffInfoList) {
        List<BankPlateResponse> list = Lists.newArrayList();
        if (CollectionUtils.isEmpty(salaryList) || CollectionUtils.isEmpty(staffInfoList)) {
            return list;
        }
        List<String> staffIdList = staffInfoList.stream().map(BasicStaffInfoEntity::getId).collect(Collectors.toList());
        List<StaffPayrollInfo> staffPayrollInfoList = staffPayrollInfoRepository.findByCompanyIdAndStaffIdIn(companyId, staffIdList);
        Map<String, StaffPayrollInfo> staffPayrollInfoMap = staffPayrollInfoList.stream().collect(Collectors.toMap(staffPayrollInfo -> staffPayrollInfo.getStaff().getId(), Function.identity()));
        Map<String, BasicStaffInfoEntity> staffMap = staffInfoList.stream().collect(Collectors.toMap(BasicStaffInfoEntity::getId, Function.identity()));
        for (StaffSalaryResponse salary : salaryList) {
            if (salary == null || !staffMap.containsKey(salary.getStaffId())) {
                continue;
            }
            BasicStaffInfoEntity staffInfoEntity = staffMap.get(salary.getStaffId());
            BankPlateResponse bankPlateResponse = new BankPlateResponse();
            bankPlateResponse.setStaffName(staffInfoEntity.getStaffName());
            bankPlateResponse.setIdCardNo(staffInfoEntity.getIdCardNo());
            bankPlateResponse.setRemark("");
            //银行信息填充
            if (staffPayrollInfoMap.containsKey(salary.getStaffId())) {
                StaffPayrollInfo staffPayrollInfo = staffPayrollInfoMap.get(salary.getStaffId());
                if (staffPayrollInfo != null && staffPayrollInfo.getStaffBankCard() != null) {
                    StaffBankCard staffBankCard = staffPayrollInfo.getStaffBankCard();
                    bankPlateResponse.setBankCardHolderName(staffBankCard.getBankCardHolderName1());
                    bankPlateResponse.setBankCardName(staffBankCard.getBankName1());
                    bankPlateResponse.setBankCardNo(staffBankCard.getBankCardNo1());
                }
            }
            String salaryFieldCode = reportRequest.getSalaryFieldCode();
            if (StringUtils.isNotBlank(salaryFieldCode)) {//根据传入的列，默认为 实发合计
                if (checkMergeSummaryDate(salary.getSummaryData(), salaryFieldCode)) {
                    bankPlateResponse.setMoney(salary.getSummaryData().getData().get(salaryFieldCode).getCellValue());
                }
            } else {//默认获取 实发合计
                if (checkMergeSummaryDate(salary.getSummaryData(), TOTAL_TAKE_HOME_PAY)) {
                    bankPlateResponse.setMoney(salary.getSummaryData().getData().get(TOTAL_TAKE_HOME_PAY).getCellValue());
                }
            }
            list.add(bankPlateResponse);
        }

        return list;
    }

    private Boolean checkSummaryDate(StaffSalarySnapshot staffSalarySnapshot, String fieldCode) {
        Boolean hasData = false;
        if (staffSalarySnapshot != null && staffSalarySnapshot.getData() != null && staffSalarySnapshot.getData().containsKey(fieldCode)) {
            hasData = true;
        }
        return hasData;
    }

    private Boolean checkMergeSummaryDate(StaffSalaryData staffSalaryData, String fieldCode) {
        Boolean hasData = false;
        if (staffSalaryData != null && staffSalaryData.getData() != null && staffSalaryData.getData().containsKey(fieldCode)) {
            hasData = true;
        }
        return hasData;
    }


    @Override
    public PageData<BankPlateResponse> queryBankPlate(String companyId, SalaryReportRequest reportRequest) {
        List<BasicStaffInfoEntity> staffList = queryStaffList(companyId, reportRequest);
        if (CollectionUtils.isEmpty(staffList)) {
            return new PageData<>(0, 0, Lists.newArrayList());
        }
        List<String> staffIdList = staffList.stream().map(BasicStaffInfoEntity::getId).collect(Collectors.toList());
        if (reportRequest.getEnableReport() == null || !reportRequest.getEnableReport()) {//薪资报表
            Page<StaffPayPeriodTermSalary> page = staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdTermIdAndIdStaffIdIn(companyId, reportRequest.getTermId(), staffIdList, reportRequest.getPageable());
            List<BankPlateResponse> list = getBankPlateList(companyId, reportRequest, page.getContent(), staffList);
            return new PageData<>(page.getTotalPages(), page.getTotalElements(), list);
        } else {//合并报表
            MergeSalaryReportTermSalary termSalary = mergeSalaryReportTermSalaryService.queryTermSalary(companyId, reportRequest.getMergeReportId(), reportRequest.getTermDate(), reportRequest.getIndexno());
            if (termSalary == null) {
                return new PageData<>(0, 0, Lists.newArrayList());
            }
            PageData<StaffSalaryResponse> page = mergeReportStaffSalaryService.queryStaffListSalaryPage(companyId, staffIdList, termSalary.getId(), reportRequest.getPageable());
            List<BankPlateResponse> list = getMergeReportBankPlateList(companyId, reportRequest, page.getContent(), staffList);
            return new PageData<>(page.getTotalPages(), page.getTotalElements(), list);
        }
    }

    private List<BasicStaffInfoEntity> queryStaffList(String companyId, SalaryReportRequest reportRequest) {
        Ihr360Specification<SyncedBasicStaffInfo> specification = (Ihr360Specification<SyncedBasicStaffInfo>) reportRequest.getSpecification();
        if (specification != null && CollectionUtils.isEmpty(specification.getPredications())) {
            specification = null;
        }
        return basicStaffInfoService.getStaffsIncludeNoPage(companyId, specification);
    }

    /**
     * 组装银行导盘导出数据
     */
    private List<List<Object>> getBankPlateDateList(List<BankPlateResponse> list) {
        List<List<Object>> datas = new ArrayList<>();
        if (org.apache.commons.collections.CollectionUtils.isEmpty(list)) {
            return datas;
        }
        for (BankPlateResponse response : list) {
            List<Object> rowData = new ArrayList<>();
            rowData.add(response.getStaffName());
            rowData.add(response.getBankCardHolderName());
            rowData.add(response.getIdCardNo());
            rowData.add(response.getBankCardName());
            rowData.add(response.getBankCardNo());
            rowData.add(response.getMoney());
            rowData.add(response.getRemark());
            datas.add(rowData);
        }
        return datas;
    }


    /**
     * 获取银行导盘导出表头
     */
    private Map<String, String> getExportBankPlateHeaderMap() {
        Map<String, String> headerMap = new LinkedHashMap<>();
        headerMap.put("staffName", "姓名");
        headerMap.put("bankCardHolderName", "开户名");
        headerMap.put("idCardNo", "证件号");
        headerMap.put("bankCardName", "开户银行");
        headerMap.put("bankCardNo", "银行账号");
        headerMap.put("money", "金额");
        headerMap.put("remark", "备注");
        return headerMap;
    }

    @Override
    public void exportBankPlate(String companyId, SalaryReportRequest reportRequest, OutputStream out) {
        //获取银行导盘导出表头
        Map<String, String> headerMap = getExportBankPlateHeaderMap();
        ExportParams exportParams = new ExportParams();
        exportParams.setHeaderMap(headerMap);
        //获取数据
        List<BankPlateResponse> list = Lists.newArrayList();
        if (reportRequest.getEnableReport() == null || !reportRequest.getEnableReport()) {//薪资历史账期
            List<StaffPayPeriodTermSalary> salaryList = staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdTermId(companyId, reportRequest.getTermId());
            if (CollectionUtils.isNotEmpty(salaryList)) {
                List<String> staffIdList = salaryList.stream().map(StaffPayPeriodTermSalary::getStaffId).collect(Collectors.toList());
                List<BasicStaffInfoEntity> staffList = basicStaffInfoService.getStaffList(companyId, staffIdList);
                list = getBankPlateList(companyId, reportRequest, salaryList, staffList);
            }
        } else {//合并报表
            MergeSalaryReportTermSalary termSalary = mergeSalaryReportTermSalaryService.queryTermSalary(companyId, reportRequest.getMergeReportId(), reportRequest.getTermDate(), reportRequest.getIndexno());
            if (termSalary != null) {
                List<StaffSalaryResponse> responseList = mergeReportStaffSalaryService.queryStaffSalaryList(companyId, termSalary.getId());
                if (CollectionUtils.isNotEmpty(responseList)) {
                    List<String> staffIdList = responseList.stream().map(StaffSalaryResponse::getStaffId).collect(Collectors.toList());
                    List<BasicStaffInfoEntity> staffList = basicStaffInfoService.getStaffList(companyId, staffIdList);
                    list = getMergeReportBankPlateList(companyId, reportRequest, responseList, staffList);
                }
            }
        }
        List<List<Object>> datas = this.getBankPlateDateList(list);
        //导出
        try {
            exportParams.setRowDatas(datas);
            ExcelUtil.exportExcel(exportParams, out);
            out.close();
        } catch (IOException e) {
            logger.error("银行导盘导出失败：" + e);
            throw new Ihr360Exception(null, "银行导盘数据导出失败！");
        }
    }

    @Override
    public void exportSalaryReport(String companyId, SalaryReportRequest reportRequest, OutputStream out) {
        List<BasicStaffInfoEntity> staffList = queryStaffList(companyId, reportRequest);
        if (CollectionUtils.isEmpty(staffList)) {
            throw new Ihr360Exception(null, "银行导盘数据为空！");
        }
        List<String> staffIdList = staffList.stream().map(BasicStaffInfoEntity::getId).collect(Collectors.toList());
        List<StaffPayPeriodTermSalary> salaryList = staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdTermIdAndIdStaffIdIn(companyId, reportRequest.getTermId(), staffIdList);
        List<StaffSalaryResponse> list = getStaffSalaryResponse(companyId, salaryList);
        //表头数据
        SalaryHeader header = historySalaryPlanService.queryStaffSalaryHead(companyId, reportRequest);
        Map<String, String> headerMap = getExportSalaryReportHeaderMap(header);
        ExportParams exportParams = new ExportParams();
        exportParams.setHeaderMap(headerMap);
        List<List<Object>> datas = this.getSalaryReportDateList(list, header);
        //导出
        try {
            exportParams.setRowDatas(datas);
            ExcelUtil.exportExcel(exportParams, out);
            out.close();
        } catch (IOException e) {
            logger.error("薪资报表导出失败：" + e);
            throw new Ihr360Exception(null, "薪资报表数据导出失败！");
        }
    }

    /**
     * 组装薪资报表导出数据
     */
    private List<List<Object>> getSalaryReportDateList(List<StaffSalaryResponse> list, SalaryHeader salaryHeader) {
        List<List<Object>> datas = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return datas;
        }
        if (salaryHeader == null || CollectionUtils.isEmpty(salaryHeader.getHeadMap())) {
            return datas;
        }
        Map<String, SalaryFieldEntity> headMap = salaryHeader.getHeadMap();
        for (StaffSalaryResponse response : list) {
            if (response == null) {
                continue;
            }
            List<Object> rowData = new ArrayList<>();
            rowData.add(response.getStaffName());
            rowData.add(response.getDepartmentName());
            rowData.add(response.getMobileNo());
            if (response.getSummaryData() != null && MapUtils.isNotEmpty(response.getSummaryData().getData())) {
                Map<String, DynamicCell> summaryData = response.getSummaryData().getData();
                for (Map.Entry<String, SalaryFieldEntity> entry : headMap.entrySet()) {
                    SalaryFieldEntity entity = entry.getValue();
                    String code = entity.getColumnName();
                    if (SyncedBasicStaffInfo.Field.staffName.equals(code) || SyncedBasicStaffInfo.Field.departmentName.equals(code) ||
                            SyncedBasicStaffInfo.Field.mobileNo.equals(code)) {
                        continue;
                    }
                    if (summaryData.containsKey(code)) {
                        DynamicCell cell = summaryData.get(code);
                        if (cell != null) {
                            rowData.add(cell.getCellValue());
                        }
                    } else {
                        rowData.add("");
                    }
                }
            }
            datas.add(rowData);
        }
        return datas;
    }


    /**
     * 获取薪资报表导出表头
     */
    private Map<String, String> getExportSalaryReportHeaderMap(SalaryHeader header) {
        Map<String, String> headerMap = new LinkedHashMap<>();
        for (Map.Entry<String, SalaryFieldEntity> entry : header.getHeadMap().entrySet()) {
            SalaryFieldEntity entity = entry.getValue();
            headerMap.put(entity.getColumnName(), entity.getFieldName());
        }
        return headerMap;
    }

    @Override
    public List<StaffPayPeriodTermSalary> queryMergeSalaryList(String companyId, List<Long> termIdList, List<String> staffIdList) {
        return staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdTermIdInAndIdStaffIdIn(companyId, termIdList, staffIdList);
    }

    @Override
    public List<StaffPayPeriodTermSalary> getByCompanyIdAndStaffIdOrderBySalaryTime(String companyId, String staffId) {
        return staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdStaffId(companyId, staffId);
    }

    @Override
    public Page<StaffPayPeriodTermSalary> queryMergeSalaryPage(String companyId, List<Long> termIdList, List<String> staffIdList, Pageable pageable) {
        return staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdTermIdInAndIdStaffIdIn(companyId, termIdList, staffIdList, pageable);
    }

    @Override
    public SalaryReportResponse queryApprovalStaffSalary(String companyId, SalaryReportRequest reportRequest, Long historyPayPeriodId) {
        SalaryReportResponse reportResponse = new SalaryReportResponse();
        List<BasicStaffInfoEntity> staffList = queryStaffList(companyId, reportRequest);
        if (CollectionUtils.isEmpty(staffList)) {
            return reportResponse;
        }
        HistoryPayPeriod historyPayPeriod = historyPayPeriodService.getOne(historyPayPeriodId);
        if (historyPayPeriod == null) {
            return reportResponse;
        }
        List<PayPeriodTerm> termList = historyPayPeriod.getTerms();
        if (CollectionUtils.isEmpty(termList)) {
            return reportResponse;
        }
        List<Long> termIdList = termList.stream().map(PayPeriodTerm::getId).collect(Collectors.toList());
        List<String> staffIdList = staffList.stream().map(BasicStaffInfoEntity::getId).collect(Collectors.toList());
        Page<StaffPayPeriodTermSalary> page = staffPayPeriodTermSalaryRepository.findByCompanyIdAndIdTermIdInAndIdStaffIdIn(companyId, termIdList, staffIdList, reportRequest.getPageable());
        List<StaffSalaryResponse> list = getStaffSalaryResponse(companyId, page.getContent());
        reportResponse.setStaffSalary(new PageData<>(page.getTotalPages(), page.getTotalElements(), list));
        return reportResponse;
    }
}
